package org.hs.phd.common.framesource;

import static com.googlecode.javacv.cpp.opencv_core.cvCopy;

import java.awt.Rectangle;

import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_imgproc;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_core.IplROI;
import com.googlecode.javacv.cpp.opencv_highgui;

public class FolderFrameSource implements FrameSource{
	
	
	private final String filePathPrefix;
	private final String suffix;
	private int currentFrameNo;
	private Rectangle roi;
	private final int startFrameNo;

	public FolderFrameSource( String filePathPrefix, String suffix, int startFrameNo){
		this.filePathPrefix = filePathPrefix;
		this.suffix = suffix;
		this.startFrameNo = startFrameNo;
		currentFrameNo = startFrameNo;
		
	}
	
	@Override
	public ImageSequenceFrame loadNextFrame(){
		currentFrameNo++;
		return loadCurrentFrame();
	}

	@Override
	public ImageSequenceFrame loadPreviousFrame() {
		currentFrameNo--;
		return loadCurrentFrame();
	}


	private ImageSequenceFrame loadCurrentFrame() {
		
		String currentImageFileName = filePathPrefix + currentFrameNo + suffix;
		
		IplImage readImage = opencv_highgui.cvLoadImage(currentImageFileName);
		if( roi == null || readImage == null ) return new DefaultImageSequenceFrameImpl( currentFrameNo, readImage);
		
		opencv_core.cvSetImageROI(readImage, opencv_core.cvRect(roi.x, roi.y, roi.width, roi.height));
		IplImage result1 = opencv_core.cvCreateImage(opencv_core.cvSize(roi.width, roi.height), readImage.depth(), readImage.nChannels());
		cvCopy(readImage, result1);
		opencv_core.cvReleaseImage(readImage);
		
		IplImage result2 = opencv_core.cvCreateImage(opencv_core.cvSize(roi.width/2, roi.height/2), result1.depth(), result1.nChannels());
		opencv_imgproc.cvPyrDown(result1, result2, opencv_imgproc.CV_GAUSSIAN_5x5);
		opencv_core.cvReleaseImage(result1);

		return new DefaultImageSequenceFrameImpl( currentFrameNo, result2);
	}

	@Override
	public void setROI(Rectangle roi) {
		this.roi = roi;
	}

	@Override
	public FramePlayer createPlayer(int interFrameMilliseconds,
			FrameProcessor frameProcessor) {
		return new DefaultFramePlayer(this, interFrameMilliseconds, frameProcessor);
	}

	@Override
	public void reset() {
		currentFrameNo = startFrameNo;
	}

}
